package com.kc.config.shiro;

import com.kc.config.shiro.cache.ShiroRedisCacheManager;
import com.kc.filter.ShiroTokenRolesAccess;
import com.kc.filter.TokenAccess;
import com.kc.service.ShiroService;
import org.apache.shiro.mgt.DefaultSessionStorageEvaluator;
import org.apache.shiro.mgt.DefaultSubjectDAO;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;
import java.util.HashMap;
import java.util.Map;

//shiro的配置类
@Configuration
public class ShiroConfig {


    @Bean("securityManager")
    public DefaultWebSecurityManager getManager(Myrealm myrealm){
        DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
        //设置我们自己的
        manager.setRealm(myrealm);

        /*
         * 关闭shiro自带的session，详情见文档
         * http://shiro.apache.org/session-management.html#SessionManagement-StatelessApplications%28Sessionless%29
         */
        DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO();
        DefaultSessionStorageEvaluator defaultSessionStorageEvaluator = new DefaultSessionStorageEvaluator();
        //禁用session会话，但是并非完全禁用.详情参看官方文档
        defaultSessionStorageEvaluator.setSessionStorageEnabled(false);
        subjectDAO.setSessionStorageEvaluator(defaultSessionStorageEvaluator);
        //设置redis缓存
        manager.setCacheManager(new ShiroRedisCacheManager());
        manager.setSubjectDAO(subjectDAO);
        return manager;
    }

    @Bean("shiroFilter")
    public ShiroFilterFactoryBean shiroFilter(DefaultWebSecurityManager manager,ShiroService shiroService){

        ShiroFilterFactoryBean filterFactoryBean = new ShiroFilterFactoryBean();

        filterFactoryBean.setSecurityManager(manager);

        //设置我们自己的权限过滤器
        Map<String, Filter> filterMap = new HashMap<>();
        filterMap.put("token",new TokenAccess());
        filterMap.put("role",new ShiroTokenRolesAccess());
        filterFactoryBean.setFilters(filterMap);

        //添加三个常用的放行url，其他
        filterFactoryBean.setFilterChainDefinitionMap(shiroService.LoadAccountUrl());
        return filterFactoryBean;
    }


    @Bean
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor(){
        return new LifecycleBeanPostProcessor();
    }

    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager manager){
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(manager);
        return authorizationAttributeSourceAdvisor;
    }

    @Bean
    public Myrealm myrealm(){
        Myrealm myrealm = new Myrealm();
        return myrealm;
    }

    //不可添加Bean，不然spring会自动注册成filter
    public TokenAccess tokenAccess(){
        TokenAccess tokenAccess = new TokenAccess();
        return tokenAccess;
    }

    //不可添加Bean，不然spring会自动注册成filter
    public ShiroTokenRolesAccess shiroTokenRolesAccess(){
        ShiroTokenRolesAccess shiroTokenRolesAccess = new ShiroTokenRolesAccess();
        return shiroTokenRolesAccess;
    }

}
